package com.tarena.lbs.activity.service.impl;

import com.tarena.lbs.activity.dao.repository.ActivityRepository;
import com.tarena.lbs.activity.pojo.param.ActivityAddParam;
import com.tarena.lbs.activity.pojo.query.ActivityQuery;
import com.tarena.lbs.activity.pojo.vo.ActivityVO;
import com.tarena.lbs.activity.service.ActivityService;
import com.tarena.lbs.base.protocol.exception.BusinessException;
import com.tarena.lbs.base.protocol.pager.PageResult;
import com.tarena.lbs.business.api.StoreApi;
import com.tarena.lbs.business.api.pojo.dto.StoreDTO;
import com.tarena.lbs.coupon.api.CouponApi;
import com.tarena.lbs.user.api.UserApi;
import com.tarena.lbs.user.api.pojo.dto.UserDTO;
import com.tarena.lbs.user.api.pojo.dto.UserGroupDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 活动服务实现类
 *
 * @author tarena
 */
@Service
@Slf4j
public class ActivityServiceImpl implements ActivityService {

    @Autowired
    private ActivityRepository activityRepository;

    @DubboReference
    private StoreApi storeApi;

    @DubboReference
    private UserApi userApi;

    @DubboReference
    private CouponApi couponApi;

    // 1. 修改saveActivity方法中的区域查询逻辑
    @Override
    public void saveActivity(ActivityAddParam param) throws BusinessException, ParseException {
        log.info("Service层保存活动，参数: {}", param);
    
        // 参数校验
        validateActivityParam(param);
    
        // 如果用户选择了区域而不是直接选择店铺，需要调用StoreApi根据区域查询店铺
        if (param.getAreaIds() != null && !param.getAreaIds().isEmpty()) {
            try {
                // 确保level不为null（由于validateActivityParam已校验，这里应该不会为null）
                Integer level = param.getAreaLevel();
                log.info("[来源:saveActivity]调用business模块的StoreApi根据区域查询店铺，areaIds: {}, level: {}", 
                         param.getAreaIds(), level);
                
                List<StoreDTO> stores = storeApi.getStoreByCity(param.getAreaIds(), level);
                
                if (stores == null || stores.isEmpty()) {
                    throw new BusinessException("所选区域下没有找到对应的店铺", "ErrorCode.NO_STORES_IN_AREA");
                }
                
                // 将查询到的店铺ID转换为逗号分隔的字符串，设置到活动参数中
                String shopIdsStr = stores.stream()
                        .map(store -> String.valueOf(store.getId()))
                        .collect(Collectors.joining(","));
                
                param.setShopIds(shopIdsStr);
                log.info("根据区域查询到店铺数量: {}, 店铺ID列表: {}", stores.size(), shopIdsStr);
            } catch (Exception e) {
                log.error("[来源:saveActivity]调用business模块的StoreApi查询店铺失败, 参数: {}", param, e);
                throw new BusinessException("查询店铺信息失败", "ErrorCode.STORE_QUERY_FAILED");
            }
        }
    
        // 验证用户分组是否存在
        validateUserGroups(param.getTargetCustomer());
    
        // 处理活动时间
        validateAndFormatDate(param);
    
        // 调用repository层保存活动
        activityRepository.saveActivity(param, param.getStartDate(), param.getEndDate());
        log.info("保存活动成功");
    }


    /**
     * 验证用户分组信息
     */
    // 修改 validateUserGroups 方法，使用 getUserGroupById 方法验证每个用户组
    private void validateUserGroups(String targetCustomer) throws BusinessException {
        if (targetCustomer == null || targetCustomer.trim().isEmpty()) {
            throw new BusinessException("请至少选择一个用户分组", "ErrorCode.USER_GROUP_NOT_EXIST");
        }

        // 验证用户分组ID格式
        String[] groupIds = targetCustomer.split(",");
        for (String groupId : groupIds) {
            try {
                Integer id = Integer.parseInt(groupId.trim());
                // 使用 getUserGroupById 验证每个用户组是否存在
                UserGroupDTO userGroup = userApi.getUserGroupById(id);
                if (userGroup == null) {
                    throw new BusinessException("用户分组不存在: " + groupId, "ErrorCode.USER_GROUP_NOT_EXIST");
                }
            } catch (NumberFormatException e) {
                throw new BusinessException("用户分组ID格式错误: " + groupId, "ErrorCode.USER_GROUP_ID_INVALID");
            }
        }
    }

    /**
     * 验证活动基本参数
     */
    private void validateActivityParam(ActivityAddParam param) throws BusinessException {
        if (param == null) {
            throw new BusinessException("活动参数不能为空", "ErrorCode.ACTIVITY_PARAM_INVALID");

        }

        if (param.getActivityName() == null || param.getActivityName().trim().isEmpty()) {
            throw new BusinessException("活动名称不能为空", "ErrorCode.ACTIVITY_NAME_INVALID");
        }

        if (param.getActivityName().length() > 30) {
            throw new BusinessException("活动名称不能超过30个字符", "ErrorCode.ACTIVITY_NAME_INVALID");
        }

        if (param.getActivityTarget() == null || param.getActivityTarget().trim().isEmpty()) {
            throw new BusinessException("活动目标不能为空", "ErrorCode.ACTIVITY_TARGET_INVALID");
        }

        if (param.getDescribes() == null || param.getDescribes().trim().isEmpty()) {
            throw new BusinessException("活动说明不能为空", "ErrorCode.ACTIVITY_DESC_INVALID");
        }

        // 区域参数校验
        // 区域参数校验
        if ((param.getAreaIds() != null && !param.getAreaIds().isEmpty()) && param.getAreaLevel() == null) {
        throw new BusinessException("请选择区域级别", "ErrorCode.AREA_LEVEL_INVALID");
        }
        
        if (param.getAreaLevel() != null && (param.getAreaIds() == null || param.getAreaIds().isEmpty())) {
        throw new BusinessException("请选择区域", "ErrorCode.AREA_ID_INVALID");
        }

        // 区域级别校验
        if (param.getAreaLevel() != null && (param.getAreaLevel() < 1 || param.getAreaLevel() > 3)) {
            throw new BusinessException("区域级别无效，只能是1(省)、2(市)、3(区)", "ErrorCode.AREA_LEVEL_INVALID");
        }

        // 确保至少选择了一种店铺选择方式
        if ((param.getAreaIds() == null || param.getAreaIds().isEmpty()) &&
            (param.getShopIds() == null || param.getShopIds().trim().isEmpty())) {
            throw new BusinessException("请选择店铺或选择区域自动获取店铺", "ErrorCode.STORE_NOT_SELECTED");
        }
    }

    /**
     * 验证和格式化日期
     */
    private void validateAndFormatDate(ActivityAddParam param) throws ParseException, BusinessException {
        if (param.getStartDate() == null || param.getStartDate().trim().isEmpty()) {
            throw new BusinessException("活动开始时间不能为空", "ErrorCode.ACTIVITY_START_DATE_INVALID");
        }

        if (param.getEndDate() == null || param.getEndDate().trim().isEmpty()) {
            throw new BusinessException("活动结束时间不能为空", "ErrorCode.ACTIVITY_END_DATE_INVALID");
        }

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date start = sdf.parse(param.getStartDate());
        Date end = sdf.parse(param.getEndDate());
        Date now = new Date();

        // 允许活动开始时间等于当前时间或者晚于当前时间，但不能早于当前时间
        if (start.before(now)) {
            // 检查是否是因为秒级精度问题导致的错误
            long timeDiff = now.getTime() - start.getTime();
            // 如果时间差小于1秒，认为是系统时间精度问题，允许通过
            if (timeDiff >= 1000) { // 1000毫秒 = 1秒
                throw new BusinessException("活动开始时间不能早于当前时间", "ErrorCode.ACTIVITY_START_DATE_INVALID");
            }
        }

        if (end.before(start)) {
            throw new BusinessException("活动结束时间不能早于开始时间", "ErrorCode.ACTIVITY_END_DATE_INVALID");
        }
    }

    /**
     * 验证店铺信息
     */
    private void validateStores(String shopIdsStr) throws BusinessException {
        if (shopIdsStr == null || shopIdsStr.trim().isEmpty()) {
            throw new BusinessException("请至少选择一个店铺", "ErrorCode.STORE_NOT_EXIST");
        }

        List<Integer> shopIdList;
        try {
            // 将逗号分隔的字符串拆分为多个店铺ID
            shopIdList = Arrays.stream(shopIdsStr.split(","))
                    .map(String::trim)
                    .map(Integer::parseInt)
                    .collect(Collectors.toList());
        } catch (NumberFormatException e) {
            throw new BusinessException("店铺ID格式错误", "ErrorCode.STORE_ID_INVALID");
        }

        // 逐个检查店铺是否存在
        List<Integer> notExistShopIds = shopIdList.stream()
                    .filter(shopId -> !storeApi.checkStoreExists(shopId))
                .collect(Collectors.toList());

        if (!notExistShopIds.isEmpty()) {
            String notExistIdsStr = notExistShopIds.stream()
                    .map(String::valueOf)
                    .collect(Collectors.joining(", "));
            throw new BusinessException("店铺不存在: " + notExistIdsStr, "ErrorCode.STORE_NOT_EXIST");
        }
    }

    // 修改pageList方法中的区域查询逻辑
    @Override
    public PageResult<ActivityVO> pageList(ActivityQuery query) throws BusinessException {
        log.info("Service层查询活动列表，参数: {}", query);
        try {
            // 如果用户提供了区域参数，调用business的StoreApi根据区域查询店铺
            if (query.getAreaIds() != null && !query.getAreaIds().isEmpty() && query.getAreaLevel() != null) {
                // 验证区域级别
                if (query.getAreaLevel() < 1 || query.getAreaLevel() > 3) {
                    throw new BusinessException("区域级别无效，只能是1(省)、2(市)、3(区)", "ErrorCode.AREA_LEVEL_INVALID");
                }
                
                try {
                    // 再次检查areaLevel，确保不为null
                    if (query.getAreaLevel() == null) {
                        log.error("区域级别为null，areaIds: {}", query.getAreaIds());
                        throw new BusinessException("区域级别不能为空", "ErrorCode.AREA_LEVEL_INVALID");
                    }
                    
                    log.info("调用business模块的StoreApi根据区域查询店铺，areaIds: {}, areaLevel: {}", query.getAreaIds(), query.getAreaLevel());
                    // 直接调用business模块的StoreApi查询店铺
                    List<StoreDTO> stores = storeApi.getStoreByCity(query.getAreaIds(), query.getAreaLevel());
                    
                    if (stores == null || stores.isEmpty()) {
                        // 如果没有查询到店铺，返回空列表
                        PageResult<ActivityVO> emptyResult = new PageResult<>();
                        emptyResult.setObjects(new ArrayList<>());
                        emptyResult.setTotal((long) 0);
                        emptyResult.setPageNo(query.getPageNo());
                        emptyResult.setPageSize(query.getPageSize());
                        return emptyResult;
                    }
                    
                    // 提取店铺ID列表
                    List<Integer> storeIds = stores.stream()
                            .map(StoreDTO::getId)
                            .collect(Collectors.toList());
                    
                    // 调用repository层查询活动列表
                    PageResult<ActivityVO> result = activityRepository.pageList(query);
                    
                    // 在Service层根据店铺ID列表过滤活动
                    if (result.getObjects() != null && !result.getObjects().isEmpty()) {
                        List<ActivityVO> filteredActivities = result.getObjects().stream()
                                .filter(activity -> {
                                    if (activity.getShopIds() == null || activity.getShopIds().trim().isEmpty()) {
                                        return false;
                                    }
                                    // 检查活动的shopIds是否包含任何一个查询到的店铺ID
                                    List<Integer> activityShopIds = Arrays.stream(activity.getShopIds().split(","))
                                            .map(String::trim)
                                            .map(Integer::parseInt)
                                            .collect(Collectors.toList());
                                    return activityShopIds.stream().anyMatch(storeIds::contains);
                                })
                                .collect(Collectors.toList());
                        
                        // 更新结果集
                        result.setObjects(filteredActivities);
                        result.setTotal((long) filteredActivities.size());
                    }
                    
                    return result;
                } catch (Exception e) {
                    log.error("调用business模块的StoreApi查询店铺失败", e);
                    throw new BusinessException("查询店铺信息失败", "ErrorCode.STORE_QUERY_FAILED");
                }
            }
            
            // 没有区域参数时，直接查询活动列表
            PageResult<ActivityVO> result = activityRepository.pageList(query);
            log.info("查询活动列表成功，总条数: {}", result.getTotal());
        
            // 如果存在活动列表数据，查询优惠券名称
            if (result.getObjects() != null && !result.getObjects().isEmpty()) {
                for (ActivityVO activityVO : result.getObjects()) {
                    // 如果活动有优惠券ID，通过CouponApi查询优惠券名称
                    if (activityVO.getRewardCouponId() != null && !activityVO.getRewardCouponId().trim().isEmpty()) {
                        try {
                            // 将String类型的优惠券ID转换为Integer
                            Integer couponId = Integer.parseInt(activityVO.getRewardCouponId().trim());
                            // 调用CouponApi查询优惠券名称
                            String couponName = couponApi.getCouponNameById(couponId);
                            // 设置优惠券名称到ActivityVO
                            activityVO.setCouponName(couponName);
                        } catch (NumberFormatException e) {
                            log.warn("优惠券ID格式错误: {}", activityVO.getRewardCouponId(), e);
                        } catch (BusinessException e) {
                            log.warn("查询优惠券名称失败，couponId: {}", activityVO.getRewardCouponId(), e);
                        } catch (Exception e) {
                            log.error("查询优惠券名称发生异常，couponId: {}", activityVO.getRewardCouponId(), e);
                        }
                    }
                }
            }

            return result;
        } catch (Exception e) {
            log.error("查询活动列表失败", e);
            throw new BusinessException("查询活动列表失败", "ErrorCode.ACTIVITY_QUERY_FAILED");
        }
    }

    @Override
    public ActivityVO getActivityById(Integer id) throws BusinessException {
        log.info("Service层查询活动详情，ID: {}", id);
        try {
            ActivityVO activity = activityRepository.getActivityById(id);
            if (activity == null) {
                throw new BusinessException("活动不存在", "ErrorCode.ACTIVITY_NOT_EXIST");
            }
            return activity;
        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("查询活动详情失败，ID: {}", id, e);
            throw new BusinessException("查询活动详情失败", "ErrorCode.ACTIVITY_QUERY_DETAIL_FAILED");
        }
    }

    @Override
    public void deleteActivity(Integer id) throws BusinessException {
        log.info("Service层删除活动，ID: {}", id);
        try {
            // 验证活动是否存在
            ActivityVO activityVO = getActivityById(id);
            if (activityVO == null) {
                log.warn("活动不存在，ID: {}", id);
                throw new BusinessException();
            }

            // 调用Repository层执行假删除
            activityRepository.deleteActivity(id);
            log.info("删除活动成功，ID: {}", id);
        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("删除活动失败，ID: {}", id, e);
            throw new BusinessException();
        }
    }

    // 在ActivityServiceImpl.java的checkActivityVisible方法中完善目标人群检查逻辑
    @Override
    public Boolean checkActivityVisible(Integer userId, Integer activityId) throws BusinessException {
        log.info("检查用户是否满足活动目标人群范围，用户ID: {}, 活动ID: {}", userId, activityId);
        // 获取活动详情
        ActivityVO activityVO = getActivityById(activityId);

        if (activityVO == null) {
            log.warn("活动不存在，活动ID: {}", activityId);
            return false;
        }

        // 检查活动状态
        if (activityVO.getEnableStatus() != 1) {
            log.warn("活动未启用，活动ID: {}, 状态: {}", activityId, activityVO.getEnableStatus());
            return false;
        }

        // 检查活动时间
        Date now = new Date();
        if (now.before(activityVO.getStartDate()) || now.after(activityVO.getEndDate())) {
            log.warn("活动不在有效期内，活动ID: {}, 开始时间: {}, 结束时间: {}",
                    activityId, activityVO.getStartDate(), activityVO.getEndDate());
            return false;
        }

        // 使用 getUserGroupIds 方法检查目标人群
        if (activityVO.getTargetCustomer() != null && !activityVO.getTargetCustomer().isEmpty()) {
            log.info("检查用户是否在活动的目标人群范围内，目标人群: {}", activityVO.getTargetCustomer());

            // 获取用户所属的用户组ID列表
            List<Integer> userGroupIds = userApi.getUserGroupIds(userId, activityVO.getBusinessId());
            log.info("用户所属的用户组数量: {}", userGroupIds.size());

            // 将活动目标人群ID字符串转换为List
            List<Integer> targetGroupIds = Arrays.stream(activityVO.getTargetCustomer().split(","))
                    .map(String::trim)
                    .map(Integer::parseInt)
                    .collect(Collectors.toList());

            // 检查用户组是否有交集
            boolean hasCommonGroup = false;
            for (Integer groupId : userGroupIds) {
                if (targetGroupIds.contains(groupId)) {
                    hasCommonGroup = true;
                    break;
                }
            }

            if (!hasCommonGroup) {
                log.warn("用户不在活动的目标人群范围内，用户ID: {}, 活动ID: {}", userId, activityId);
                return false;
            }
        }

        return true;
    }

    @Override
    public List<UserDTO> getUsersByIds(String userIds) {
        log.info("根据用户ID列表获取用户信息，userIds: {}", userIds);
        try {
            List<Integer> idList = Arrays.stream(userIds.split(","))
                    .map(String::trim)
                    .map(Integer::parseInt)
                    .collect(Collectors.toList());
            // 直接将String类型的userIds传递给UserApi.getUsersByIds方法
            return userApi.getUsersByIds(userIds);
        } catch (Exception e) {
            log.error("获取用户信息失败: {}", e.getMessage(), e);
            return Collections.emptyList();
        }
    }

    @Override
    public UserGroupDTO getUserGroupById(Integer groupId) {
        log.info("获取用户分组信息，groupId: {}", groupId);
        try {
            return userApi.getUserGroupById(groupId);
        } catch (Exception e) {
            log.error("获取用户分组信息失败: {}", e.getMessage(), e);
            return null;
        }
    }

    @Override
    public void updateActivityStatus(Integer id, Integer enableStatus) {
        log.info("更新活动状态，id: {}, enableStatus: {}", id, enableStatus);
        try {
            activityRepository.updateActivityStatus(id, enableStatus);
        } catch (Exception e) {
            log.error("更新活动状态失败: {}", e.getMessage(), e);
            throw new RuntimeException("更新活动状态失败", e);
        }
    }

}